﻿using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Coder.Workflow;
using Coder.Workflow.Searcher;
using Fee.FileAttachs;
using Fee.IO.Importers;
using Fee.Orders;
using Fee.Orders.AuthProjectWorkflow;
using Fee.Stores;
using Identity;
using JwtWebApi.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace JwtWebApi.Controllers
{
    public class AuthProjectController : WorkflowBaseController<AuthProjectManager<ApplicationDbContext>, AuthProjectOrder>
    {
        private readonly IConstructionTaskStore<ApplicationDbContext> _constructionTaskStore;
        private readonly ApplicationDbContext _dbContext;
        private readonly FileManager _fileManager;
        private readonly AuthProjectManager<ApplicationDbContext> _orderManager;
        

        public AuthProjectController(AuthProjectManager<ApplicationDbContext> orderManager,
            IConstructionTaskStore<ApplicationDbContext> constructionTaskStore,
            ApplicationDbContext dbContext,  FileManager fileManager)
            : base(orderManager,
                dbContext)
        {
            _constructionTaskStore = constructionTaskStore;
            _dbContext = dbContext;
        
            _fileManager = fileManager;
            _orderManager = orderManager;
        }

    

        [HttpGet("myTask")]
        public IActionResult GetMyTask([FromQuery]WorkActivitySearcher searcher)
        {
            var task = OrderManager.GetMyTask(searcher, out var total);
            foreach (var item in task)
            {
                if (item.WorkTask == null)
                    _dbContext.Entry(item).Reference(f => f.WorkTask).Load();
            }
            return Json(new
            {
                data = task,
                total
            });
        }

        [HttpPost("create/{workActivityId?}")]
        public async Task<IActionResult> CreateByFile([FromForm] IFormFile formFile, [FromRoute]int? id)
        {
            var user = _dbContext.GetByUserName(User.Identity.Name);
            var filePath = _fileManager.GetTempPrivateFile(Path.GetExtension(formFile.FileName), User.Identity);

            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await formFile.CopyToAsync(stream).ContinueWith(task => { stream.Dispose(); });
            }

            var import =
                new AuthProjectImport<ApplicationDbContext>(_dbContext, _orderManager, user, _constructionTaskStore, workActivityId: id);
            var result = import.Import(filePath, out var importResult, out var resultPath);


            return Json(new
            {
                FilePath = filePath,
                costDetail = result ? import.StationCostDetails() : null,
                resultPath,
                successed = result,
                message = result ? "成功提交订单" : "失败，查看结果文件"
            });
        }

        [HttpPost("submit-auth-number/{id:int}")]
        public IActionResult SubmitAuthNumber([FromBody] SubmitProjectNumber model, int id)
        {
            var authProjectOrder = _dbContext.Set<AuthProjectOrder>().FirstOrDefault(f => f.Id == id);
            if (authProjectOrder == null)
                return NotFound("没有找到id为" + id + "的完工会审单");
            authProjectOrder.AuthProjectNumber = model.ProjectNumber;
            _dbContext.Update(authProjectOrder);
            _dbContext.SaveChanges();

            return Json(new
            {
                order = authProjectOrder,
                successed = true,
                message = "成功保存发文号"
            });
        }

        [HttpPost("submit-to-order/{workActivityId?}")]
        public IActionResult CreateOrder([FromBody] StartWorkflowModel format, [FromRoute]int? workActivityId)
        {
            var user = _dbContext.GetByUserName(User.Identity.Name);
            var import = new AuthProjectImport<ApplicationDbContext>(_dbContext, _orderManager, user,
                _constructionTaskStore, workActivityId, true);
            var result = import.Import(format.ServerFileName, out var importResult, out var resultPath);



            return Json(new
            {
                order = result ? import.OrderResult.Order : null,
                resultPath,

                workActivity = import.CurrentWorkActivity,
                successed = result,
                message = result ? "成功提交订单" : "失败，查看结果文件"
            });
        }


        #region Attachement

        [HttpDelete("attach/{taskId:int}/{fileAttachId:int}")]
        public IActionResult DeleteAttach([FromRoute] int fileAttachId, [FromRoute] int taskId)
        {
            var order
                = _dbContext.Set<AuthProjectOrder>().Include(_ => _.Attaches).ThenInclude(_ => _.File.UploadUser)
                    .FirstOrDefault(f => f.Id == taskId);

            for (var index = 0; index < order.Attaches.Count; index++)
            {
                var attach = order.Attaches[index];
                if (attach.FileId == fileAttachId)
                {
                    System.IO.File.Delete(order.Attaches[index].File.SystemPath);
                    order.Attaches.RemoveAt(index);
                    break;
                }
            }

            _dbContext.SaveChanges();
            return Json(new
            {
                success = true,
                message = "删除成功"
            });
        }

        [HttpPost("attach/{id:int}")]
        public async Task<IActionResult> UploadAttach([FromRoute] int id
            , [FromForm] IFormFile formFile)
        {
            var filePath = _fileManager.GetAuthProjectFileTask(Path.GetExtension(formFile.FileName), id);

            var stream = new FileStream(filePath, FileMode.Create);


            var copyTask = formFile.CopyToAsync(stream).ContinueWith(task => { stream.Dispose(); });


            var attach = new FileAttach(formFile.FileName, filePath)
            {
                UploadUser = _dbContext.GetByUserName(User.Identity.Name)
            };

            var order
                = _dbContext.Set<AuthProjectOrder>().Include(_ => _.Attaches).ThenInclude(_ => _.File.UploadUser)
                    .FirstOrDefault(f => f.Id == id);

            order.Attaches.Add(new AuthProjectOrderFileAttach
            {
                File = attach,
                Order = order
            });
            await copyTask;
            _dbContext.SaveChanges();
            return Json(new
            {
                successed = true
            });
        }

        [HttpGet("attach/{orderId:int}")]
        public IActionResult ListAttach([FromRoute] int orderId)
        {
            var attaches
                = _dbContext.Set<AuthProjectOrder>()
                    .Include(_ => _.Attaches).ThenInclude(_ => _.File).ThenInclude(f => f.UploadUser)
                    .Where(f => f.Id == orderId).SelectMany(f => f.Attaches).Select(_ => new
                    {
                        _.File.Id,
                        _.File.CreateTime,
                        _.File.Name,
                        Uploader = _.File.UploadUser != null ? _.File.UploadUser.Name : ""
                    });


            return Json(attaches);
        }

        [HttpGet("attach/{id:int}/{fileAttachId:int}")]
        public IActionResult GetBlobDownload([FromRoute] int fileAttachId, [FromRoute] int id)
        {
            var file = _dbContext.Set<FileAttach>().FirstOrDefault(f => f.Id == fileAttachId);

            var filePath = file.SystemPath;
            var contentType = "application/octet-stream";
            var fileName = file.Name;
            return File(System.IO.File.OpenRead(filePath), contentType, fileName);
        }

        #endregion
    }

    public class SubmitProjectNumber
    {
        public string ProjectNumber { get; set; }
    }

    public class SubmitToNextStep
    {
        public string Comment { get; set; }

        public string NextUserId { get; set; }
    }

    public class StartWorkflowModel
    {
        public string ServerFileName { get; set; }
    }
}